package edu.mse.camel.client.playback.views;


import java.util.List;
import java.util.Observable;
import java.util.Observer;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.part.ViewPart;

import edu.mse.camel.client.chat.message.IMessage;
import edu.mse.camel.client.eventbus.pubsub.EventManager;
import edu.mse.camel.client.eventbus.pubsub.ISubscriber;
import edu.mse.camel.client.events.EventIDs;
import edu.mse.camel.client.events.IEvent;
import edu.mse.camel.client.playback.events.ReceiveGenericPeerEventList;


/**
 * the playback view is used to display the content of chat 
 * and associated model change.
 */

public class PlaybackView extends ViewPart implements Observer, ISubscriber {

	private int scrollIndex;
	private int modelIndex;
	
	@Override
	public void dispose() {
		// TODO Auto-generated method stub
		EventManager.getInstance().unSubscribeTo(EventIDs.NOTIFY_SYNC_FINISHED_EVENT, this);
		super.dispose();
	}

	private StyledText messageViewer;

//	private TableViewer viewer;

	 
	/**
	 * The constructor.
	 */
	public PlaybackView() {
//		PlaybackMessageList.getInstance().addObserver(this);
		ReceiveGenericPeerEventList.getInstance().addObserver(this);
		EventManager.getInstance().subscribeTo(EventIDs.NOTIFY_SYNC_FINISHED_EVENT, this);
		scrollIndex=0;
		modelIndex=0;
	}

	/**
	 * This is a callback that will allow us
	 * to create the viewer and initialize it.
	 */
	public void createPartControl(Composite parent) {
		
		messageViewer = new StyledText(parent, SWT.V_SCROLL | SWT.MULTI);
		GridData messageViewerData = new GridData();
		messageViewerData.heightHint = 200;
		messageViewerData.horizontalAlignment = GridData.FILL;
		messageViewerData.verticalAlignment = GridData.FILL;
		messageViewerData.grabExcessHorizontalSpace = false;
		messageViewerData.grabExcessVerticalSpace = true;
		messageViewer.setLayoutData(messageViewerData);
		messageViewer.setEditable(false);

	}

	private void decorateMessage(IMessage message) {
		int startOffset;
		int length;
		String append;
		
		String content = message.getContent().trim();
		StyleRange styleRange = new StyleRange();
		
		if(message.getName().length()>0) {
			append = message.getTimeStamp() + " " + message.getName() + " :" + content + System.getProperty("line.separator");
			styleRange.foreground = new Color(Display.getDefault(), message.getColor());
		}
		else {
			
			if(modelIndex == ReceiveGenericPeerEventList.getInstance().getCurrentIndex()){
				scrollIndex = PlaybackMessageList.getInstance().getMessages().indexOf(message);
				append = "*" + content + System.getProperty("line.separator");
				styleRange.foreground = Display.getCurrent().getSystemColor(SWT.COLOR_BLUE);	
			}
			else {
				append = content + System.getProperty("line.separator");				
			}
			
			modelIndex++;

		}

		startOffset = messageViewer.getText().length();
		length = append.length();

		styleRange.start = startOffset;
		styleRange.length = length;
		
		messageViewer.append(append);
		messageViewer.setStyleRange(styleRange);
		
	}

	private void showMessageList() {

		List<IMessage> messages = PlaybackMessageList.getInstance().getMessages();

		messageViewer.setText("");
		scrollIndex=0;
		modelIndex=0;

		for (IMessage message : messages) {
			decorateMessage(message);
		}

//		messageViewer.setTopIndex(messageViewer.getLineCount());
		messageViewer.setTopIndex(scrollIndex);
		
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		messageViewer.setFocus();
	}

	@Override
	public void update(Observable o, Object arg) {
		Display.getDefault().syncExec(new Runnable() {
			@Override
			public void run() {
				if (messageViewer != null) {
					messageViewer.redraw();
					showMessageList();
				}
			}
		});
		
	}

	@Override
	public void notifyEvent(IEvent e) {
		if(e.getEventID().equalsIgnoreCase(EventIDs.NOTIFY_SYNC_FINISHED_EVENT)){
			Display.getDefault().syncExec(new Runnable() {
				@Override
				public void run() {
					showMessageList();
				}
			});
		}
	
	}
}